/*
 ============================================================================
 Name        : HPC.c
 Author      : Bruno Strasser
 Version     : 0.1
 Copyright   : Your copyright notice
 Description : Compute Pi in MPI C++
 ============================================================================
 */
#include <math.h> 
#include <mpi/mpi.h>
#include <iostream>
#include "Utils.h"
#include "Data.cpp"

#define MASTER 0

using namespace std;

void leerInfo(void * &buff, unsigned int &buffsize) {
//TODO
	buff = NULL;
	buffsize = 0;
}

void crearPrimerTupla() {
	//TODO
	/*
	 * Leer la info y crear las primeras tuplas
	 * y enviarselas a todos los procesos
	 * */
}

int main(int argc, char *argv[]) {
	int numAct,	T;
	int* numPreds;
	int* numModes;
	int** Preds;
	int** ModesCosts;
	int** ModesTimes;

	printf("argv[1]: \"%s\"\n", argv[1]);

	if ((argc != 2) || readDppmSpec(argv[1],numAct,T,numPreds,Preds,numModes,ModesCosts,ModesTimes)){
			printf("Error!!\n");
			return -1;
	}

	DppmParams dppm;
	InitializeDppm(dppm,numAct,T,numPreds,Preds,numModes,ModesCosts,ModesTimes);

	return 0;
}

	/*int size, rank;
	MPI::Init(argc, argv);
	size = MPI::COMM_WORLD.Get_size();
	rank = MPI::COMM_WORLD.Get_rank();
	MPI_Status * status;

	Data * d = NULL;

	void * buff;
	void * cond;
	unsigned int buffsize;

	if (rank == MASTER) {

		//############# BEGIN : ENVIAR INFO A TODOS LOS NODOS

		int cantAct = 8; //cantidad de actividades
		//envio cant de actividades
		MPI_Bcast(&cantAct, 1, MPI_INT, rank, MPI_COMM_WORLD);

		//deadline
		int T = 120;
		MPI_Bcast(&T, 1, MPI_INT, rank, MPI_COMM_WORLD);

		//envio los Si
		int * S = new int[cantAct]; //TODO falta inicializar
		MPI_Bcast(S, cantAct, MPI_INT, rank, MPI_COMM_WORLD);

		//inicalizar la cantidad de modos de cada actividad
		int * R = new int[cantAct];

		d = crearData(cantAct, T, S, R); //creo el datatype donde se almacena la info;

		//PARA CADA ACTIVIDAD
		for (int i = 0; i < cantAct; i++) {

			//envio Ri
			MPI_Bcast(R+i, 1, MPI_INT, rank, MPI_COMM_WORLD);

			//envio los tiempos
			int * t = new int[R[i]]; //TODO inicializar los tik
			MPI_Bcast(t, R[i], MPI_INT, rank, MPI_COMM_WORLD);

			//envio los costos
			int * c = new int[R[i]]; //TODO inicializar los cik
			MPI_Bcast(c, R[i], MPI_INT, rank, MPI_COMM_WORLD);

			//cantidad de predecesores;
			int cantPred = 4; //TODO inicializar;
			MPI_Bcast(&cantPred, 1, MPI_INT, rank, MPI_COMM_WORLD);

			//array que tiene los id de los predecesores
			int * P = new int[cantPred]; //TODO inicializar
			MPI_Bcast(P, cantPred, MPI_INT, rank, MPI_COMM_WORLD);

			//creo el modo,el nodo y los agrego al datatype

			Node * n = crearNode(cantPred,P);
			//agregarNodeData(d,n,i);
			//destruirNode(n); //agrega una copia limpia

			Modes * m = crearModo(R[i], t, c);
			//agregarModoData(d, m, i);
			//destruirModo(m); //agrega una copia limpia

			delete[] t;
			delete[] c;
			delete[] P;

		}

		delete[] R;
		delete[] S;

		//############# END   : ENVIAR INFO A TODOS LOS NODOS

		//############# BEGIN : CREAR LAS PRIMERAS TUPLAS Y DISTRIBUIRLAS

		int cantTuplas = d->R[0];

		if (cantTuplas > 0) { //tengo tuplas para mandar

			//les aviso a todos que tengo tuplas

			MPI_Allreduce(cond, cond, 1, MPI_INT, MPI_MAX OR,	MPI_COMM_WORLD);
			MPI_Bcast(&cantTuplas, 1, MPI_INT, MASTER, MPI_COMM_WORLD);

			//creo las primeras tuplas
			int ** tuplas = new int*[cantTuplas];
			for(int i = 0; i < cantTuplas; i++){

				tuplas[i] = new int[d->cantAct];
				tuplas[i][0] = d->modes[0][i]->Ri;

				for(int j = 1; j < d->cantAct; j++)
					tuplas[i][j] = -1;

			}
			int resto = cantTuplas % size;

			if (rest <> 0){


			}

		} else { //no tengo tuplas

			MPI_Allreduce(cond, cond, 0, MPI_INT, MPI_MAX OR, MPI_COMM_WORLD);

		}

		//############# END : CREAR LAS PRIMERAS TUPLAS Y DISTRIBUIRLAS

	} else { //no soy el MASTER

		//############# BEGIN : RECIBIR INFO DEL ROOT

		//tengo que recibir la informacion del Broadcast del root y crear el datatype Data

		int cantAct;
		MPI_Recv(&cantAct, 1, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

		int T;
		MPI_Recv(&T, 1, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

		int * S = new int[cantAct];
		MPI_Recv(S, cantAct, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

		int * R = new int[cantAct];
		MPI_Recv(R, cantAct, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

		d = crearData(cantAct, T, S, R);

		//PARA CADA ACTIVIDAD
		for (int i = 0; i < cantAct; i++) {

			//recibo los tiempos
			int * t;
			MPI_Recv(t, R[i], MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

			//recibo los costos
			int * c;
			MPI_Recv(c, R[i], MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

			//cantidad de predecesores;
			int cantPred;
			MPI_Recv(&cantPred, 1, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

			//array que tiene los id de los predecesores
			int * P;
			MPI_Recv(P, cantPred, MPI_INT, MASTER, 0, MPI_COMM_WORLD, status);

			//creo el modo, el nodo y se los agrego al datatype

			Node * n = crearNode(cantPred,P);
			//agregarNodeData(d,n,i);
			//destruirNode(n); //agrega una copia limpia del nodo

			Modes * m = crearModo(R[i], t, c);
			//agregarModoData(d, m, i);
			//destruirModo(m); //agrega una copia limpia del modo

			delete[] t;
			delete[] c;
			delete[] P;

		}

		delete[] R;
		delete[] S;


		//############# END : RECIBIR INFO DEL ROOT

		 Espero que me avise si tiene tuplas
		 *
		 *
		MPI_Allreduce(cond, cond, 0yo no tengo nada, MPI_INT,
				MPI_MAX OR, MPI_COMM_WORLD);
	}

	//si hay tuplas tengo cosas pa hacer
	while (cond == 1) {

	MPI_Scatter(buff,buffsize,MPI_BYTE,buff,)

}

if (rank == 0) {
	printf("Hay %d procesos", size);

}
MPI::Finalize();

return 0;

}*/

